#include "messagequeue.h"
#include <QCoreApplication>
#include <QDebug>

MessageQueue::MessageQueue(QObject *parent)
    : QObject(parent)
{

}

MessageQueue::~MessageQueue()
{

}

void MessageQueue::publish(QEvent* event)
{
    QMutexLocker locker(&m_mutex);

    if (event == nullptr)
        return;

    quint16 id = event->type();

    if (m_subscriber.contains(id))
    {
        QList<QObject*> value = m_subscriber.value(id);
        CustomEvent *e = static_cast<CustomEvent*>(event);
        foreach (QObject* v, value)
        {
            QCoreApplication::postEvent(v, e->clone()); // 注意event必须在堆里才可以
        }
    }
}

void MessageQueue::publish(QObject *obj, QEvent *event)
{
    QMutexLocker locker(&m_mutex);

    CustomEvent* e = (CustomEvent*)event;
    if (e == nullptr)
        return;

    quint16 id = event->type();

    if (m_subscriber.contains(id))
    {
        QList<QObject*> value = m_subscriber.value(id);
        foreach (QObject* v, value)
        {
            if (v == obj)
                QCoreApplication::postEvent(v, e); // 注意event必须在堆里才可以
        }
    }

    delete event;
}

void MessageQueue::subscribe(quint16 id, QObject* who)
{
    QMutexLocker locker(&m_mutex);

    if (who == nullptr)
        return;

    if (m_subscriber.contains(id))
    {
        QList<QObject*> value = m_subscriber.value(id);
        if (value.contains(who))
            return;

        value.push_back(who);
        m_subscriber.insert(id, value);
        return;
    }

    QList<QObject*> value;
    value.push_back(who);
    m_subscriber.insert(id, value);
}

void MessageQueue::unsubscribe(quint16 id, QObject* who)
{
    QMutexLocker locker(&m_mutex);

    if (who == nullptr)
        return;

    if (m_subscriber.contains(id))
    {
        QList<QObject*> value = m_subscriber.value(id);
        if (value.contains(who))
        {
            m_subscriber[id].removeOne(who);
            if (!m_subscriber[id].size())
                m_subscriber.remove(id);
            return;
        }
    }
}
